home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / game / shoot / ADoom_src_1_2.lha / ADoom_src / f_finale.c < prev    next >
C/C++ Source or Header  |  1998-02-21  |  15KB  |  742 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    Game completion, final screen animation.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24.  
  25. static const char
  26. rcsid[] = "$Id: f_finale.c,v 1.5 1997/02/03 21:26:34 b1 Exp $";
  27.  
  28. #include <ctype.h>
  29.  
  30. // Functions.
  31. #include "i_system.h"
  32. #include "i_video.h"
  33. #include "m_swap.h"
  34. #include "z_zone.h"
  35. #include "v_video.h"
  36. #include "w_wad.h"
  37. #include "s_sound.h"
  38.  
  39. // Data.
  40. #include "dstrings.h"
  41. #include "sounds.h"
  42.  
  43. #include "doomstat.h"
  44. #include "r_state.h"
  45.  
  46. // ?
  47. //#include "doomstat.h"
  48. //#include "r_local.h"
  49. //#include "f_finale.h"
  50.  
  51. // Stage of animation:
  52. //  0 = text, 1 = art screen, 2 = character cast
  53. int        finalestage;
  54.  
  55. int        finalecount;
  56.  
  57. #define    TEXTSPEED    3
  58. #define    TEXTWAIT    250
  59.  
  60. char*    e1text = E1TEXT;
  61. char*    e2text = E2TEXT;
  62. char*    e3text = E3TEXT;
  63. char*    e4text = E4TEXT;
  64.  
  65. char*    c1text = C1TEXT;
  66. char*    c2text = C2TEXT;
  67. char*    c3text = C3TEXT;
  68. char*    c4text = C4TEXT;
  69. char*    c5text = C5TEXT;
  70. char*    c6text = C6TEXT;
  71.  
  72. char*    p1text = P1TEXT;
  73. char*    p2text = P2TEXT;
  74. char*    p3text = P3TEXT;
  75. char*    p4text = P4TEXT;
  76. char*    p5text = P5TEXT;
  77. char*    p6text = P6TEXT;
  78.  
  79. char*    t1text = T1TEXT;
  80. char*    t2text = T2TEXT;
  81. char*    t3text = T3TEXT;
  82. char*    t4text = T4TEXT;
  83. char*    t5text = T5TEXT;
  84. char*    t6text = T6TEXT;
  85.  
  86. char*    finaletext;
  87. char*    finaleflat;
  88.  
  89. void    F_StartCast (void);
  90. void    F_CastTicker (void);
  91. boolean F_CastResponder (event_t *ev);
  92. void    F_CastDrawer (void);
  93.  
  94. //
  95. // F_StartFinale
  96. //
  97. void F_StartFinale (void)
  98. {
  99.     gameaction = ga_nothing;
  100.     gamestate = GS_FINALE;
  101.     viewactive = false;
  102.     automapactive = false;
  103.  
  104.     // Okay - IWAD dependend stuff.
  105.     // This has been changed severly, and
  106.     //  some stuff might have changed in the process.
  107.     switch ( gamemode )
  108.     {
  109.  
  110.       // DOOM 1 - E1, E3 or E4, but each nine missions
  111.       case shareware:
  112.       case registered:
  113.       case retail:
  114.       {
  115.     S_ChangeMusic(mus_victor, true);
  116.     
  117.     switch (gameepisode)
  118.     {
  119.       case 1:
  120.         finaleflat = "FLOOR4_8";
  121.         finaletext = e1text;
  122.         break;
  123.       case 2:
  124.         finaleflat = "SFLR6_1";
  125.         finaletext = e2text;
  126.         break;
  127.       case 3:
  128.         finaleflat = "MFLR8_4";
  129.         finaletext = e3text;
  130.         break;
  131.       case 4:
  132.         finaleflat = "MFLR8_3";
  133.         finaletext = e4text;
  134.         break;
  135.       default:
  136.         // Ouch.
  137.         break;
  138.     }
  139.     break;
  140.       }
  141.       
  142.       // DOOM II and missions packs with E1, M34
  143.       case commercial:
  144.       {
  145.       S_ChangeMusic(mus_read_m, true);
  146.  
  147.       switch (gamemap)
  148.       {
  149.         case 6:
  150.           finaleflat = "SLIME16";
  151.           finaletext = c1text;
  152.           break;
  153.         case 11:
  154.           finaleflat = "RROCK14";
  155.           finaletext = c2text;
  156.           break;
  157.         case 20:
  158.           finaleflat = "RROCK07";
  159.           finaletext = c3text;
  160.           break;
  161.         case 30:
  162.           finaleflat = "RROCK17";
  163.           finaletext = c4text;
  164.           break;
  165.         case 15:
  166.           finaleflat = "RROCK13";
  167.           finaletext = c5text;
  168.           break;
  169.         case 31:
  170.           finaleflat = "RROCK19";
  171.           finaletext = c6text;
  172.           break;
  173.         default:
  174.           // Ouch.
  175.           break;
  176.       }
  177.       break;
  178.       }    
  179.  
  180.    
  181.       // Indeterminate.
  182.       default:
  183.     S_ChangeMusic(mus_read_m, true);
  184.     finaleflat = "F_SKY1"; // Not used anywhere else.
  185.     finaletext = c1text;  // FIXME - other text, music?
  186.     break;
  187.     }
  188.     
  189.     finalestage = 0;
  190.     finalecount = 0;
  191.     
  192. }
  193.  
  194.  
  195.  
  196. boolean F_Responder (event_t *event)
  197. {
  198.     if (finalestage == 2)
  199.     return F_CastResponder (event);
  200.     
  201.     return false;
  202. }
  203.  
  204.  
  205. //
  206. // F_Ticker
  207. //
  208. void F_Ticker (void)
  209. {
  210.     int        i;
  211.     
  212.     // check for skipping
  213.     if ( (gamemode == commercial)
  214.       && ( finalecount > 50) )
  215.     {
  216.       // go on to the next level
  217.       for (i=0 ; i<MAXPLAYERS ; i++)
  218.     if (players[i].cmd.buttons)
  219.       break;
  220.                 
  221.       if (i < MAXPLAYERS)
  222.       {    
  223.     if (gamemap == 30)
  224.       F_StartCast ();
  225.     else
  226.       gameaction = ga_worlddone;
  227.       }
  228.     }
  229.     
  230.     // advance animation
  231.     finalecount++;
  232.     
  233.     if (finalestage == 2)
  234.     {
  235.     F_CastTicker ();
  236.     return;
  237.     }
  238.     
  239.     if ( gamemode == commercial)
  240.     return;
  241.         
  242.     if (!finalestage && finalecount>strlen (finaletext)*TEXTSPEED + TEXTWAIT)
  243.     {
  244.     finalecount = 0;
  245.     finalestage = 1;
  246.     wipegamestate = -1;        // force a wipe
  247.     if (gameepisode == 3)
  248.         S_StartMusic (mus_bunny);
  249.     }
  250. }
  251.  
  252.  
  253.  
  254. //
  255. // F_TextWrite
  256. //
  257.  
  258. #include "hu_stuff.h"
  259. extern    patch_t *hu_font[HU_FONTSIZE];
  260.  
  261.  
  262. void F_TextWrite (void)
  263. {
  264.     byte*    src;
  265.     byte*    dest;
  266.     
  267.     int        x,y,w;
  268.     int        count;
  269.     char*    ch;
  270.     int        c;
  271.     int        cx;
  272.     int        cy;
  273.     
  274.     // erase the entire screen to a tiled background
  275.     src = W_CacheLumpName ( finaleflat , PU_CACHE);
  276.     dest = screens[0];
  277.     
  278.     for (y=0 ; y<SCREENHEIGHT ; y++)
  279.     {
  280.     for (x=0 ; x<SCREENWIDTH/64 ; x++)
  281.     {
  282.         memcpy (dest, src+((y&63)<<6), 64);
  283.         dest += 64;
  284.     }
  285.     if (SCREENWIDTH&63)
  286.     {
  287.         memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
  288.         dest += (SCREENWIDTH&63);
  289.     }
  290.     }
  291.  
  292.     // draw some of the text onto the screen
  293.     cx = 10;
  294.     cy = 10;
  295.     ch = finaletext;
  296.     
  297.     count = (finalecount - 10)/TEXTSPEED;
  298.     if (count < 0)
  299.     count = 0;
  300.     for ( ; count ; count-- )
  301.     {
  302.     c = *ch++;
  303.     if (!c)
  304.         break;
  305.     if (c == '\n')
  306.     {
  307.         cx = 10;
  308.         cy += 11;
  309.         continue;
  310.     }
  311.         
  312.     c = toupper(c) - HU_FONTSTART;
  313.     if (c < 0 || c> HU_FONTSIZE)
  314.     {
  315.         cx += 4;
  316.         continue;
  317.     }
  318.         
  319.     w = SWAPSHORT (hu_font[c]->width);
  320.     if (cx+w > SCREENWIDTH)
  321.         break;
  322.     V_DrawPatchInDirect(cx, cy, 0, hu_font[c]);
  323.     cx+=w;
  324.     }
  325.     
  326.     I_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  327.     
  328. }
  329.  
  330. //
  331. // Final DOOM 2 animation
  332. // Casting by id Software.
  333. //   in order of appearance
  334. //
  335. typedef struct
  336. {
  337.     char        *name;
  338.     mobjtype_t    type;
  339. } castinfo_t;
  340.  
  341. castinfo_t    castorder[] = {
  342.     {CC_ZOMBIE, MT_POSSESSED},
  343.     {CC_SHOTGUN, MT_SHOTGUY},
  344.     {CC_HEAVY, MT_CHAINGUY},
  345.     {CC_IMP, MT_TROOP},
  346.     {CC_DEMON, MT_SERGEANT},
  347.     {CC_LOST, MT_SKULL},
  348.     {CC_CACO, MT_HEAD},
  349.     {CC_HELL, MT_KNIGHT},
  350.     {CC_BARON, MT_BRUISER},
  351.     {CC_ARACH, MT_BABY},
  352.     {CC_PAIN, MT_PAIN},
  353.     {CC_REVEN, MT_UNDEAD},
  354.     {CC_MANCU, MT_FATSO},
  355.     {CC_ARCH, MT_VILE},
  356.     {CC_SPIDER, MT_SPIDER},
  357.     {CC_CYBER, MT_CYBORG},
  358.     {CC_HERO, MT_PLAYER},
  359.  
  360.     {NULL,0}
  361. };
  362.  
  363. int        castnum;
  364. int        casttics;
  365. state_t*    caststate;
  366. boolean        castdeath;
  367. int        castframes;
  368. int        castonmelee;
  369. boolean        castattacking;
  370.  
  371.  
  372. //
  373. // F_StartCast
  374. //
  375. extern    gamestate_t     wipegamestate;
  376.  
  377.  
  378. void F_StartCast (void)
  379. {
  380.     wipegamestate = -1;        // force a screen wipe
  381.     castnum = 0;
  382.     caststate = &states[mobjinfo[castorder[castnum].type].seestate];
  383.     casttics = caststate->tics;
  384.     castdeath = false;
  385.     finalestage = 2;    
  386.     castframes = 0;
  387.     castonmelee = 0;
  388.     castattacking = false;
  389.     S_ChangeMusic(mus_evil, true);
  390. }
  391.  
  392.  
  393. //
  394. // F_CastTicker
  395. //
  396. void F_CastTicker (void)
  397. {
  398.     int        st;
  399.     int        sfx;
  400.     
  401.     if (--casttics > 0)
  402.     return;            // not time to change state yet
  403.         
  404.     if (caststate->tics == -1 || caststate->nextstate == S_NULL)
  405.     {
  406.     // switch from deathstate to next monster
  407.     castnum++;
  408.     castdeath = false;
  409.     if (castorder[castnum].name == NULL)
  410.         castnum = 0;
  411.     if (mobjinfo[castorder[castnum].type].seesound)
  412.         S_StartSound (NULL, mobjinfo[castorder[castnum].type].seesound);
  413.     caststate = &states[mobjinfo[castorder[castnum].type].seestate];
  414.     castframes = 0;
  415.     }
  416.     else
  417.     {
  418.     // just advance to next state in animation
  419.     if (caststate == &states[S_PLAY_ATK1])
  420.         goto stopattack;    // Oh, gross hack!
  421.     st = caststate->nextstate;
  422.     caststate = &states[st];
  423.     castframes++;
  424.     
  425.     // sound hacks....
  426.     switch (st)
  427.     {
  428.       case S_PLAY_ATK1:    sfx = sfx_dshtgn; break;
  429.       case S_POSS_ATK2:    sfx = sfx_pistol; break;
  430.       case S_SPOS_ATK2:    sfx = sfx_shotgn; break;
  431.       case S_VILE_ATK2:    sfx = sfx_vilatk; break;
  432.       case S_SKEL_FIST2:    sfx = sfx_skeswg; break;
  433.       case S_SKEL_FIST4:    sfx = sfx_skepch; break;
  434.       case S_SKEL_MISS2:    sfx = sfx_skeatk; break;
  435.       case S_FATT_ATK8:
  436.       case S_FATT_ATK5:
  437.       case S_FATT_ATK2:    sfx = sfx_firsht; break;
  438.       case S_CPOS_ATK2:
  439.       case S_CPOS_ATK3:
  440.       case S_CPOS_ATK4:    sfx = sfx_shotgn; break;
  441.       case S_TROO_ATK3:    sfx = sfx_claw; break;
  442.       case S_SARG_ATK2:    sfx = sfx_sgtatk; break;
  443.       case S_BOSS_ATK2:
  444.       case S_BOS2_ATK2:
  445.       case S_HEAD_ATK2:    sfx = sfx_firsht; break;
  446.       case S_SKULL_ATK2:    sfx = sfx_sklatk; break;
  447.       case S_SPID_ATK2:
  448.       case S_SPID_ATK3:    sfx = sfx_shotgn; break;
  449.       case S_BSPI_ATK2:    sfx = sfx_plasma; break;
  450.       case S_CYBER_ATK2:
  451.       case S_CYBER_ATK4:
  452.       case S_CYBER_ATK6:    sfx = sfx_rlaunc; break;
  453.       case S_PAIN_ATK3:    sfx = sfx_sklatk; break;
  454.       default: sfx = 0; break;
  455.     }
  456.         
  457.     if (sfx)
  458.         S_StartSound (NULL, sfx);
  459.     }
  460.     
  461.     if (castframes == 12)
  462.     {
  463.     // go into attack frame
  464.     castattacking = true;
  465.     if (castonmelee)
  466.         caststate=&states[mobjinfo[castorder[castnum].type].meleestate];
  467.     else
  468.         caststate=&states[mobjinfo[castorder[castnum].type].missilestate];
  469.     castonmelee ^= 1;
  470.     if (caststate == &states[S_NULL])
  471.     {
  472.         if (castonmelee)
  473.         caststate=
  474.             &states[mobjinfo[castorder[castnum].type].meleestate];
  475.         else
  476.         caststate=
  477.             &states[mobjinfo[castorder[castnum].type].missilestate];
  478.     }
  479.     }
  480.     
  481.     if (castattacking)
  482.     {
  483.     if (castframes == 24
  484.         ||    caststate == &states[mobjinfo[castorder[castnum].type].seestate] )
  485.     {
  486.       stopattack:
  487.         castattacking = false;
  488.         castframes = 0;
  489.         caststate = &states[mobjinfo[castorder[castnum].type].seestate];
  490.     }
  491.     }
  492.     
  493.     casttics = caststate->tics;
  494.     if (casttics == -1)
  495.     casttics = 15;
  496. }
  497.  
  498.  
  499. //
  500. // F_CastResponder
  501. //
  502.  
  503. boolean F_CastResponder (event_t* ev)
  504. {
  505.     if (ev->type != ev_keydown)
  506.     return false;
  507.         
  508.     if (castdeath)
  509.     return true;            // already in dying frames
  510.         
  511.     // go into death frame
  512.     castdeath = true;
  513.     caststate = &states[mobjinfo[castorder[castnum].type].deathstate];
  514.     casttics = caststate->tics;
  515.     castframes = 0;
  516.     castattacking = false;
  517.     if (mobjinfo[castorder[castnum].type].deathsound)
  518.     S_StartSound (NULL, mobjinfo[castorder[castnum].type].deathsound);
  519.     
  520.     return true;
  521. }
  522.  
  523.  
  524. void F_CastPrint (char* text)
  525. {
  526.     char*    ch;
  527.     int        c;
  528.     int        cx;
  529.     int        w;
  530.     int        width;
  531.     
  532.     // find width
  533.     ch = text;
  534.     width = 0;
  535.     
  536.     while (ch)
  537.     {
  538.     c = *ch++;
  539.     if (!c)
  540.         break;
  541.     c = toupper(c) - HU_FONTSTART;
  542.     if (c < 0 || c> HU_FONTSIZE)
  543.     {
  544.         width += 4;
  545.         continue;
  546.     }
  547.         
  548.     w = SWAPSHORT (hu_font[c]->width);
  549.     width += w;
  550.     }
  551.     
  552.     // draw it
  553.     cx = 160-width/2;
  554.     ch = text;
  555.     while (ch)
  556.     {
  557.     c = *ch++;
  558.     if (!c)
  559.         break;
  560.     c = toupper(c) - HU_FONTSTART;
  561.     if (c < 0 || c> HU_FONTSIZE)
  562.     {
  563.         cx += 4;
  564.         continue;
  565.     }
  566.         
  567.     w = SWAPSHORT (hu_font[c]->width);
  568.     V_DrawPatchInDirect(cx, 180, 0, hu_font[c]);
  569.     cx+=w;
  570.     }
  571.     
  572. }
  573.  
  574.  
  575. //
  576. // F_CastDrawer
  577. //
  578. //void V_DrawPatchFlipped (int x, int y, int scrn, patch_t *patch);
  579.  
  580. void F_CastDrawer (void)
  581. {
  582.     spritedef_t*    sprdef;
  583.     spriteframe_t*    sprframe;
  584.     int            lump;
  585.     boolean        flip;
  586.     patch_t*        patch;
  587.     
  588.     // erase the entire screen to a background
  589.     V_DrawPatchInDirect (0,0,0, W_CacheLumpName ("BOSSBACK", PU_CACHE));
  590.  
  591.     F_CastPrint (castorder[castnum].name);
  592.     
  593.     // draw the current frame in the middle of the screen
  594.     sprdef = &sprites[caststate->sprite];
  595.     sprframe = &sprdef->spriteframes[ caststate->frame & FF_FRAMEMASK];
  596.     lump = sprframe->lump[0];
  597.     flip = (boolean)sprframe->flip[0];
  598.             
  599.     patch = W_CacheLumpNum (lump+firstspritelump, PU_CACHE);
  600.     if (flip)
  601.     V_DrawPatchInDirectFlipped (160,170,0,patch);
  602.     else
  603.     V_DrawPatchInDirect (160,170,0,patch);
  604. }
  605.  
  606.  
  607. //
  608. // F_DrawPatchCol
  609. //
  610. void
  611. F_DrawPatchCol
  612. ( int        x,
  613.   patch_t*    patch,
  614.   int        col )
  615. {
  616.     column_t*    column;
  617.     byte*    source;
  618.     byte*    dest;
  619.     byte*    desttop;
  620.     int        count;
  621.     
  622.     column = (column_t *)((byte *)patch + SWAPLONG(patch->columnofs[col]));
  623. //    desttop = screens[0]+x;
  624.     desttop = screens[0]+x+(SCREENWIDTH-320)/2+SCREENWIDTH*((SCREENHEIGHT-200)/2);
  625.  
  626.     // step through the posts in a column
  627.     while (column->topdelta != 0xff )
  628.     {
  629.     source = (byte *)column + 3;
  630.     dest = desttop + column->topdelta*SCREENWIDTH;
  631.     count = column->length;
  632.         
  633.     while (count--)
  634.     {
  635.         *dest = *source++;
  636.         dest += SCREENWIDTH;
  637.     }
  638.     column = (column_t *)(  (byte *)column + column->length + 4 );
  639.     }
  640. }
  641.  
  642.  
  643. //
  644. // F_BunnyScroll
  645. //
  646. void F_BunnyScroll (void)
  647. {
  648.     int        scrolled;
  649.     int        x;
  650.     patch_t*    p1;
  651.     patch_t*    p2;
  652.     char    name[10];
  653.     int        stage;
  654.     static int    laststage;
  655.         
  656.     p1 = W_CacheLumpName ("PFUB2", PU_LEVEL);
  657.     p2 = W_CacheLumpName ("PFUB1", PU_LEVEL);
  658.  
  659.     scrolled = 320 - (finalecount-230)/2;
  660.     if (scrolled > 320)
  661.     scrolled = 320;
  662.     if (scrolled < 0)
  663.     scrolled = 0;
  664.  
  665. //    for ( x=0 ; x<SCREENWIDTH ; x++)
  666.     if ((SCREENWIDTH!=320)||(SCREENHEIGHT!=200))
  667.         memset(screens[0],2,SCREENWIDTH*SCREENHEIGHT);
  668.     for ( x=0 ; x<320 ; x++)
  669.     {
  670.     if (x+scrolled < 320)
  671.         F_DrawPatchCol (x, p1, x+scrolled);
  672.     else
  673.         F_DrawPatchCol (x, p2, x+scrolled - 320);        
  674.     }
  675.     
  676.     if (finalecount < 1130)
  677.     return;
  678.     if (finalecount < 1180)
  679.     {
  680.     V_DrawPatchInDirect ((320-13*8)/2,
  681.              (200-8*8)/2,0, W_CacheLumpName ("END0",PU_CACHE));
  682.     laststage = 0;
  683.     return;
  684.     }
  685.     
  686.     stage = (finalecount-1180) / 5;
  687.     if (stage > 6)
  688.     stage = 6;
  689.     if (stage > laststage)
  690.     {
  691.     S_StartSound (NULL, sfx_pistol);
  692.     laststage = stage;
  693.     }
  694.     
  695.     sprintf (name,"END%i",stage);
  696.     V_DrawPatchInDirect ((320-13*8)/2, (200-8*8)/2,0, W_CacheLumpName (name,PU_CACHE));
  697.  
  698.     I_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  699. }
  700.  
  701.  
  702. //
  703. // F_Drawer
  704. //
  705. void F_Drawer (void)
  706. {
  707.     if (finalestage == 2)
  708.     {
  709.     F_CastDrawer ();
  710.     return;
  711.     }
  712.  
  713.     if (!finalestage)
  714.     F_TextWrite ();
  715.     else
  716.     {
  717.     switch (gameepisode)
  718.     {
  719.       case 1:
  720.         if ( gamemode == retail )
  721.           V_DrawPatchInDirect (0,0,0,
  722.              W_CacheLumpName("CREDIT",PU_CACHE));
  723.         else
  724.           V_DrawPatchInDirect (0,0,0,
  725.              W_CacheLumpName("HELP2",PU_CACHE));
  726.         break;
  727.       case 2:
  728.         V_DrawPatchInDirect(0,0,0,
  729.             W_CacheLumpName("VICTORY2",PU_CACHE));
  730.         break;
  731.       case 3:
  732.         F_BunnyScroll ();
  733.         break;
  734.       case 4:
  735.         V_DrawPatchInDirect (0,0,0,
  736.              W_CacheLumpName("ENDPIC",PU_CACHE));
  737.         break;
  738.     }
  739.     }
  740.             
  741. }
  742.